package com.zxy.ziems.server.device.service.impl;

import cn.hutool.core.util.StrUtil;
import com.zxy.ziems.server.device.convertor.DeviceConvertor;
import com.zxy.ziems.server.device.mapper.ChannelMapper;
import com.zxy.ziems.server.device.pojo.dto.ChannelDTO;
import com.zxy.ziems.server.device.pojo.entity.ChannelEntity;
import com.zxy.ziems.server.device.pojo.entity.CollectorEntity;
import com.zxy.ziems.server.device.pojo.entity.DeviceTypeEntity;
import com.zxy.ziems.server.device.pojo.entity.ProtocolEntity;
import com.zxy.ziems.server.device.pojo.vo.ChannelVO;
import com.zxy.ziems.server.device.service.*;
import com.zxy.ziems.server.mybatis.core.service.ServiceImplX;
import com.zxy.ziems.server.utils.AssertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 通信通道
 * @author 10348359
 * @create 2024-03-25 14:06
 */
@Service
public class ChannelServiceImpl extends ServiceImplX<ChannelMapper, ChannelEntity> implements ChannelService {
    @Override
    public void add(ChannelDTO dto) {
        AssertUtil.isNull(getByName(dto.getName()), "通信通道重复");
        ChannelEntity entity = DeviceConvertor.INSTANCE.communicationChannelDTOConvert2DO(dto);

        save(entity);
    }

    @Override
    public void update(ChannelDTO dto) {
        AssertUtil.nonNull(getById(dto.getId()), "通信通道不存在");
        ChannelEntity old = getByName(dto.getName());
        AssertUtil.isTrue(Objects.isNull(old) || old.getId().equals(dto.getId()), "编码重复");
        ChannelEntity entity = DeviceConvertor.INSTANCE.communicationChannelDTOConvert2DO(dto);
        updateById(entity);
    }

    @Override
    public void deleteById(String id) {
        if (StrUtil.isBlank(id)) {
            return;
        }
        removeById(id);
    }

    @Override
    public ChannelEntity getById(String id) {
        return super.getById(id);
    }

    @Override
    public ChannelVO detailById(String id) {
        ChannelEntity entity = getById(id);
        if (Objects.isNull(entity)) {
            return null;
        }
        CollectorEntity collectorEntity = collectorService.getById(entity.getCollectorId());
        ProtocolEntity protocolEntity = protocolService.getById(entity.getProtocolId());
        DeviceTypeEntity deviceTypeEntity = deviceTypeService.getByCode(entity.getDeviceTypeCode());
        return DeviceConvertor.INSTANCE.communicationChannelDOConvert2VO(entity, collectorEntity, protocolEntity, deviceTypeEntity);
    }

    @Override
    public ChannelEntity getByName(String name) {
        return getOne(ChannelEntity::getName, name);
    }

    @Override
    public List<ChannelVO> viewList() {
        List<ChannelEntity> list = list();
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        Set<String> collectorIdSet = list.stream().map(ChannelEntity::getCollectorId).collect(Collectors.toSet());
        Set<String> protocolIdSet = list.stream().map(ChannelEntity::getProtocolId).collect(Collectors.toSet());
        Set<String> deviceTypeCodeSet = list.stream().map(ChannelEntity::getDeviceTypeCode).collect(Collectors.toSet());

        List<CollectorEntity> collectorEntities = collectorService.listByIdList(collectorIdSet);
        Map<String, CollectorEntity> collectorMap = collectorEntities.stream().collect(Collectors.toMap(CollectorEntity::getId, (a) -> a));
        List<ProtocolEntity> protocolEntities = protocolService.listByIdList(protocolIdSet);
        Map<String, ProtocolEntity> protocolMap = protocolEntities.stream().collect(Collectors.toMap(ProtocolEntity::getId, (a) -> a));
        List<DeviceTypeEntity> deviceTypeEntities = deviceTypeService.listByCodes(deviceTypeCodeSet);
        Map<String, DeviceTypeEntity> deviceTypeEntityMap = deviceTypeEntities.stream().collect(Collectors.toMap(DeviceTypeEntity::getCode, (a) -> a));

        DeviceConvertor instance = DeviceConvertor.INSTANCE;
        List<ChannelVO> voList = list.stream().map((entity) -> {
            return instance.communicationChannelDOConvert2VO(entity, collectorMap.get(entity.getCollectorId()), protocolMap.get(entity.getProtocolId()), deviceTypeEntityMap.get(entity.getDeviceTypeCode()));
        }).toList();

        return voList;
    }

    @Override
    public List<ChannelEntity> listByCollectorId(String collectorId) {
        return list(ChannelEntity::getCollectorId, collectorId);
    }

    private CollectorService collectorService;

    @Autowired
    public void setCollectorService(CollectorService collectorService) {
        this.collectorService = collectorService;
    }

    private ProtocolService protocolService;

    @Autowired
    public void setProtocolService(ProtocolService protocolService) {
        this.protocolService = protocolService;
    }

    private DeviceTypeService deviceTypeService;

    @Autowired
    public void setDeviceTypeService(DeviceTypeService deviceTypeService) {
        this.deviceTypeService = deviceTypeService;
    }
}
